using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using JEng_Mark_1.Interfaces;

namespace JEng_Mark_1.Shaders
{
	public class NormalMappingEffect : IJEngShader
	{
		public enum Techniques
		{
			NormalMapping,
		}

		private Effect _baseEffect;
		///<summary>
		///Gets the underlying Effect.
		///</summary>
		public Effect BaseEffect
		{
			get { return _baseEffect; }
		}

		private bool _readyToRender = false;
		///<summary>
		///Is the shader ready to be rendered.
		///</summary>
		public bool ReadyToRender
		{
			get { return _readyToRender; }
		}

		#region Effect Parameters

		private EffectParameter _WorldParam;
		public Matrix World
		{
			get
			{
				if (_WorldParam == null)
					throw new Exception("Cannot get value of World; World EffectParameter is null.");
				return _WorldParam.GetValueMatrix();
			}
			set
			{
				if (_WorldParam == null)
					throw new Exception("Cannot set value of World; World EffectParameter is null.");
				_WorldParam.SetValue(value);
			}
		}

		private EffectParameter _ViewParam;
		public Matrix View
		{
			get
			{
				if (_ViewParam == null)
					throw new Exception("Cannot get value of View; View EffectParameter is null.");
				return _ViewParam.GetValueMatrix();
			}
			set
			{
				if (_ViewParam == null)
					throw new Exception("Cannot set value of View; View EffectParameter is null.");
				_ViewParam.SetValue(value);
			}
		}

		private EffectParameter _ProjectionParam;
		public Matrix Projection
		{
			get
			{
				if (_ProjectionParam == null)
					throw new Exception("Cannot get value of Projection; Projection EffectParameter is null.");
				return _ProjectionParam.GetValueMatrix();
			}
			set
			{
				if (_ProjectionParam == null)
					throw new Exception("Cannot set value of Projection; Projection EffectParameter is null.");
				_ProjectionParam.SetValue(value);
			}
		}

		private EffectParameter _LightPositionParam;
		public Vector3 LightPosition
		{
			get
			{
				if (_LightPositionParam == null)
					throw new Exception("Cannot get value of LightPosition; LightPosition EffectParameter is null.");
				return _LightPositionParam.GetValueVector3();
			}
			set
			{
				if (_LightPositionParam == null)
					throw new Exception("Cannot set value of LightPosition; LightPosition EffectParameter is null.");
				_LightPositionParam.SetValue(value);
			}
		}

		private EffectParameter _LightColorParam;
		public Vector4 LightColor
		{
			get
			{
				if (_LightColorParam == null)
					throw new Exception("Cannot get value of LightColor; LightColor EffectParameter is null.");
				return _LightColorParam.GetValueVector4();
			}
			set
			{
				if (_LightColorParam == null)
					throw new Exception("Cannot set value of LightColor; LightColor EffectParameter is null.");
				_LightColorParam.SetValue(value);
			}
		}

		private EffectParameter _AmbientLightColorParam;
		public Vector4 AmbientLightColor
		{
			get
			{
				if (_AmbientLightColorParam == null)
					throw new Exception("Cannot get value of AmbientLightColor; AmbientLightColor EffectParameter is null.");
				return _AmbientLightColorParam.GetValueVector4();
			}
			set
			{
				if (_AmbientLightColorParam == null)
					throw new Exception("Cannot set value of AmbientLightColor; AmbientLightColor EffectParameter is null.");
				_AmbientLightColorParam.SetValue(value);
			}
		}

		private EffectParameter _ShininessParam;
		public float Shininess
		{
			get
			{
				if (_ShininessParam == null)
					throw new Exception("Cannot get value of Shininess; Shininess EffectParameter is null.");
				return _ShininessParam.GetValueSingle();
			}
			set
			{
				if (_ShininessParam == null)
					throw new Exception("Cannot set value of Shininess; Shininess EffectParameter is null.");
				_ShininessParam.SetValue(value);
			}
		}

		private EffectParameter _SpecularPowerParam;
		public float SpecularPower
		{
			get
			{
				if (_SpecularPowerParam == null)
					throw new Exception("Cannot get value of SpecularPower; SpecularPower EffectParameter is null.");
				return _SpecularPowerParam.GetValueSingle();
			}
			set
			{
				if (_SpecularPowerParam == null)
					throw new Exception("Cannot set value of SpecularPower; SpecularPower EffectParameter is null.");
				_SpecularPowerParam.SetValue(value);
			}
		}

		private EffectParameter _NormalMapParam;
		public Texture2D NormalMap
		{
			get
			{
				if (_NormalMapParam == null)
					throw new Exception("Cannot get value of NormalMap; NormalMap EffectParameter is null.");
				return _NormalMapParam.GetValueTexture2D();
			}
			set
			{
				if (_NormalMapParam == null)
					throw new Exception("Cannot set value of NormalMap; NormalMap EffectParameter is null.");
				_NormalMapParam.SetValue(value);
			}
		}


		private EffectParameter _TextureParam;
		public Texture2D Texture
		{
			get
			{
				if (_TextureParam == null)
					throw new Exception("Cannot get value of Texture; Texture EffectParameter is null.");
				return _TextureParam.GetValueTexture2D();
			}
			set
			{
				if (_TextureParam == null)
					throw new Exception("Cannot set value of Texture; Texture EffectParameter is null.");
				_TextureParam.SetValue(value);
			}
		}


		#endregion

		#region Effect Techniques

		private EffectTechnique _NormalMappingTechnique;

		#endregion

		#region Initialize Methods

		///<summary>
		///Initializes the Effect from byte code for the given GraphicsDevice.
		///</summary
		///<param name="graphicsDevice">The GraphicsDevice for which the effect is being created.</param>
		public void Initialize(GraphicsDevice graphicsDevice)
		{
			Initialize(graphicsDevice, CompilerOptions.None, null);
		}

		///<summary>
		///Initializes the Effect from byte code for the given GraphicsDevice and CompilerOptions.
		///</summary
		///<param name="graphicsDevice">The GraphicsDevice for which the effect is being created.</param>
		///<param name="compilerOptions">The CompilerOptions to use when creating the effect.</param>
		public void Initialize(GraphicsDevice graphicsDevice, CompilerOptions compilerOptions)
		{
			Initialize(graphicsDevice, compilerOptions, null);
		}

		///<summary>
		///Initializes the Effect from byte code for the given GraphicsDevice, CompilerOptions, and EffectPool.
		///</summary
		///<param name="graphicsDevice">The GraphicsDevice for which the effect is being created.</param>
		///<param name="compilerOptions">The CompilerOptions to use when creating the effect.</param>
		///<param name="effectPools">The EffectPool to use with the effect.</param>
		public void Initialize(GraphicsDevice graphicsDevice, CompilerOptions compilerOptions, EffectPool effectPool)
		{
			_baseEffect = new Effect(graphicsDevice, byteCode, compilerOptions, effectPool);
			_readyToRender = true;

			_WorldParam = _baseEffect.Parameters["World"];
			_ViewParam = _baseEffect.Parameters["View"];
			_ProjectionParam = _baseEffect.Parameters["Projection"];
			_LightPositionParam = _baseEffect.Parameters["LightPosition"];
			_LightColorParam = _baseEffect.Parameters["LightColor"];
			_AmbientLightColorParam = _baseEffect.Parameters["AmbientLightColor"];
			_ShininessParam = _baseEffect.Parameters["Shininess"];
			_SpecularPowerParam = _baseEffect.Parameters["SpecularPower"];
			_NormalMapParam = _baseEffect.Parameters["NormalMap"];
			_TextureParam = _baseEffect.Parameters["Texture"];

			_NormalMappingTechnique = _baseEffect.Techniques["NormalMapping"];
		}

		#endregion

		///<summary>
		///Sets the current technique for the effect.
		///</summary>
		///<param name="technique">The technique to use for the current technique.</param>
		public void SetCurrentTechnique(NormalMappingEffect.Techniques technique)
		{
			switch (technique)
			{
				case NormalMappingEffect.Techniques.NormalMapping:
					_baseEffect.CurrentTechnique = _NormalMappingTechnique;
					break;

			}
		}

		#region Compiled Byte Code

		#if XBOX
		static readonly byte[] byteCode = { 1,9,255,254,204,4,0,0,0,0,0,0,3,0,0,0,2,0,0,0,96,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,87,111,114,108,100,0,61,0,3,0,0,0,2,0,0,0,200,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,86,105,101,119,0,1,61,0,3,0,0,0,2,0,0,0,48,1,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,80,114,111,106,101,99,116,105,111,110,0,0,3,0,0,0,1,0,0,0,104,1,0,0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,76,105,103,104,116,80,111,115,105,116,105,111,110,0,0,0,3,0,0,0,1,0,0,0,168,1,0,0,0,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,76,105,103,104,116,67,111,108,111,114,0,0,3,0,0,0,1,0,0,0,228,1,0,0,0,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,65,109,98,105,101,110,116,76,105,103,104,116,67,111,108,111,114,0,0,0,3,0,0,0,0,0,0,0,28,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,10,0,0,0,83,104,105,110,105,110,101,115,115,0,0,0,3,0,0,0,0,0,0,0,76,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,14,0,0,0,83,112,101,99,117,108,97,114,80,111,119,101,114,0,116,105,7,0,0,0,4,0,0,0,120,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,78,111,114,109,97,108,77,97,112,0,2,128,12,0,0,0,4,0,0,0,88,3,0,0,0,0,0,0,0,0,0,0,2,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,4,0,0,0,164,0,0,0,0,1,0,0,160,2,0,0,156,2,0,0,170,0,0,0,0,1,0,0,184,2,0,0,180,2,0,0,169,0,0,0,0,1,0,0,216,2,0,0,212,2,0,0,171,0,0,0,0,1,0,0,248,2,0,0,244,2,0,0,17,0,0,0,78,111,114,109,97,108,77,97,112,83,97,109,112,108,101,114,0,0,0,0,7,0,0,0,4,0,0,0,136,3,0,0,0,0,0,0,0,0,0,0,3,0,0,0,8,0,0,0,84,101,120,116,117,114,101,0,12,0,0,0,4,0,0,0,100,4,0,0,0,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,4,0,0,0,164,0,0,0,0,1,0,0,172,3,0,0,168,3,0,0,170,0,0,0,0,1,0,0,196,3,0,0,192,3,0,0,169,0,0,0,0,1,0,0,228,3,0,0,224,3,0,0,171,0,0,0,0,1,0,0,4,4,0,0,0,4,0,0,22,0,0,0,68,105,102,102,117,115,101,84,101,120,116,117,114,101,83,97,109,112,108,101,114,0,0,0,5,0,0,0,16,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,15,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,71,111,0,0,14,0,0,0,78,111,114,109,97,108,77,97,112,112,105,110,103,0,0,0,12,0,0,0,1,0,0,0,5,0,0,0,7,0,0,0,4,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,108,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,212,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,64,1,0,0,92,1,0,0,0,0,0,0,0,0,0,0,124,1,0,0,152,1,0,0,0,0,0,0,0,0,0,0,184,1,0,0,212,1,0,0,0,0,0,0,0,0,0,0,252,1,0,0,24,2,0,0,0,0,0,0,0,0,0,0,44,2,0,0,72,2,0,0,0,0,0,0,0,0,0,0,96,2,0,0,116,2,0,0,0,0,0,0,0,0,0,0,136,2,0,0,20,3,0,0,0,0,0,0,0,0,0,0,112,3,0,0,132,3,0,0,0,0,0,0,0,0,0,0,148,3,0,0,32,4,0,0,0,0,0,0,0,0,0,0,184,4,0,0,0,0,0,0,1,0,0,0,176,4,0,0,0,0,0,0,2,0,0,0,146,0,0,0,0,0,0,0,132,4,0,0,128,4,0,0,147,0,0,0,0,0,0,0,156,4,0,0,152,4,0,0,2,0,0,0,4,0,0,0,3,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,1,0,0,0,0,0,0,0,112,4,0,0,0,2,255,255,254,255,86,0,67,84,65,66,28,0,0,0,31,1,0,0,0,2,255,255,5,0,0,0,28,0,0,0,0,0,0,0,24,1,0,0,128,0,0,0,2,0,1,0,1,0,0,0,148,0,0,0,164,0,0,0,180,0,0,0,3,0,1,0,1,0,0,0,204,0,0,0,0,0,0,0,220,0,0,0,2,0,0,0,1,0,0,0,148,0,0,0,164,0,0,0,231,0,0,0,3,0,0,0,1,0,0,0,204,0,0,0,0,0,0,0,248,0,0,0,2,0,2,0,1,0,0,0,8,1,0,0,164,0,0,0,65,109,98,105,101,110,116,76,105,103,104,116,67,111,108,111,114,0,171,171,1,0,3,0,1,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,105,102,102,117,115,101,84,101,120,116,117,114,101,83,97,109,112,108,101,114,0,171,171,4,0,12,0,1,0,1,0,1,0,0,0,0,0,0,0,76,105,103,104,116,67,111,108,111,114,0,78,111,114,109,97,108,77,97,112,83,97,109,112,108,101,114,0,83,112,101,99,117,108,97,114,80,111,119,101,114,0,171,171,0,0,3,0,1,0,1,0,1,0,0,0,0,0,0,0,112,115,95,50,95,48,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,68,51,68,88,57,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,49,53,46,55,55,57,46,48,48,48,48,0,171,171,171,254,255,86,0,80,82,69,83,1,2,88,70,254,255,50,0,67,84,65,66,28,0,0,0,143,0,0,0,1,2,88,70,2,0,0,0,28,0,0,0,0,1,0,0,140,0,0,0,68,0,0,0,2,0,0,0,1,0,0,0,80,0,0,0,96,0,0,0,112,0,0,0,2,0,1,0,1,0,0,0,124,0,0,0,96,0,0,0,76,105,103,104,116,67,111,108,111,114,0,171,1,0,3,0,1,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,83,104,105,110,105,110,101,115,115,0,171,171,0,0,3,0,1,0,1,0,1,0,0,0,0,0,0,0,116,120,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,68,51,68,88,57,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,49,53,46,55,55,57,46,48,48,48,48,0,171,171,171,254,255,12,0,80,82,83,73,3,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,254,255,2,0,67,76,73,84,0,0,0,0,254,255,15,0,70,88,76,67,1,0,0,0,4,0,80,160,2,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,12,0,0,0,240,240,240,240,15,15,15,15,255,255,0,0,81,0,0,5,4,0,15,160,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,2,0,0,0,128,0,0,3,176,31,0,0,2,0,0,0,128,1,0,7,176,31,0,0,2,0,0,0,128,2,0,7,176,31,0,0,2,0,0,0,128,3,0,7,176,31,0,0,2,0,0,0,128,4,0,7,176,31,0,0,2,0,0,0,128,5,0,7,176,31,0,0,2,0,0,0,144,0,8,15,160,31,0,0,2,0,0,0,144,1,8,15,160,66,0,0,3,0,0,15,128,0,0,228,176,0,8,228,160,66,0,0,3,1,0,15,128,0,0,228,176,1,8,228,160,8,0,0,3,2,0,1,128,0,0,228,128,3,0,228,176,8,0,0,3,2,0,2,128,0,0,228,128,4,0,228,176,8,0,0,3,2,0,4,128,0,0,228,128,5,0,228,176,36,0,0,2,0,0,7,128,2,0,228,128,36,0,0,2,2,0,7,128,1,0,228,176,8,0,0,3,4,0,1,128,0,0,228,128,2,0,228,128,2,0,0,3,0,0,8,128,4,0,0,128,4,0,0,128,4,0,0,4,0,0,7,128,0,0,228,128,0,0,255,129,2,0,228,128,36,0,0,2,2,0,7,128,2,0,228,176,11,0,0,3,3,0,8,128,4,0,0,128,4,0,0,160,8,0,0,3,0,0,1,128,0,0,228,128,2,0,228,128,11,0,0,3,2,0,8,128,0,0,0,128,4,0,0,160,32,0,0,3,0,0,8,128,2,0,255,128,2,0,0,160,5,0,0,3,2,0,15,128,0,0,255,128,3,0,228,160,1,0,0,2,0,0,15,128,0,0,228,160,4,0,0,4,0,0,15,128,0,0,228,128,3,0,255,128,1,0,228,160,4,0,0,4,0,0,15,128,0,0,228,128,1,0,228,128,2,0,228,128,1,0,0,2,0,8,15,128,0,0,228,128,255,255,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,140,5,0,0,1,1,254,255,254,255,80,0,67,84,65,66,28,0,0,0,10,1,0,0,1,1,254,255,4,0,0,0,28,0,0,0,0,0,0,0,3,1,0,0,108,0,0,0,2,0,12,0,1,0,0,0,124,0,0,0,140,0,0,0,156,0,0,0,2,0,8,0,4,0,0,0,168,0,0,0,184,0,0,0,248,0,0,0,2,0,4,0,4,0,0,0,168,0,0,0,184,0,0,0,253,0,0,0,2,0,0,0,4,0,0,0,168,0,0,0,184,0,0,0,76,105,103,104,116,80,111,115,105,116,105,111,110,0,171,171,1,0,3,0,1,0,3,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,114,111,106,101,99,116,105,111,110,0,171,3,0,3,0,4,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,105,101,119,0,87,111,114,108,100,0,118,115,95,49,95,49,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,68,51,68,88,57,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,49,53,46,55,55,57,46,48,48,48,48,0,254,255,161,0,80,82,69,83,1,2,88,70,254,255,49,0,67,84,65,66,28,0,0,0,139,0,0,0,1,2,88,70,1,0,0,0,28,0,0,0,0,1,0,0,136,0,0,0,48,0,0,0,2,0,0,0,3,0,0,0,56,0,0,0,72,0,0,0,86,105,101,119,0,171,171,171,3,0,3,0,4,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,116,120,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,68,51,68,88,57,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,49,53,46,55,55,57,46,48,48,48,48,0,171,171,171,254,255,12,0,80,82,83,73,13,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,13,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,254,255,2,0,67,76,73,84,0,0,0,0,254,255,91,0,70,88,76,67,9,0,0,0,1,0,0,16,1,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,1,0,0,16,1,0,0,0,0,0,0,0,2,0,0,0,7,0,0,0,0,0,0,0,7,0,0,0,5,0,0,0,1,0,0,16,1,0,0,0,0,0,0,0,2,0,0,0,11,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,3,0,16,16,1,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,3,0,80,160,2,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,8,0,0,0,3,0,80,160,2,0,0,0,0,0,0,0,7,0,0,0,1,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,12,0,0,0,3,0,80,160,2,0,0,0,0,0,0,0,7,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,8,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,3,0,64,32,2,0,0,0,0,0,0,0,7,0,0,0,8,0,0,0,0,0,0,0,7,0,0,0,12,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,3,0,64,32,2,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,52,0,0,0,240,240,240,240,15,15,15,15,255,255,0,0,31,0,0,0,0,0,0,128,0,0,15,144,31,0,0,0,5,0,0,128,1,0,15,144,31,0,0,0,3,0,0,128,2,0,15,144,31,0,0,0,7,0,0,128,3,0,15,144,31,0,0,0,6,0,0,128,4,0,15,144,9,0,0,0,0,0,8,128,0,0,228,144,3,0,228,160,9,0,0,0,0,0,1,128,0,0,228,144,0,0,228,160,9,0,0,0,0,0,2,128,0,0,228,144,1,0,228,160,9,0,0,0,0,0,4,128,0,0,228,144,2,0,228,160,9,0,0,0,1,0,1,128,0,0,228,128,4,0,228,160,9,0,0,0,1,0,2,128,0,0,228,128,5,0,228,160,9,0,0,0,1,0,4,128,0,0,228,128,6,0,228,160,9,0,0,0,1,0,8,128,0,0,228,128,7,0,228,160,9,0,0,0,0,0,1,192,1,0,228,128,8,0,228,160,9,0,0,0,0,0,2,192,1,0,228,128,9,0,228,160,9,0,0,0,0,0,4,192,1,0,228,128,10,0,228,160,9,0,0,0,0,0,8,192,1,0,228,128,11,0,228,160,2,0,0,0,1,0,7,224,0,0,228,129,12,0,228,160,2,0,0,0,2,0,7,224,0,0,228,128,13,0,228,161,8,0,0,0,3,0,1,224,4,0,228,144,0,0,228,160,8,0,0,0,4,0,1,224,4,0,228,144,1,0,228,160,8,0,0,0,5,0,1,224,4,0,228,144,2,0,228,160,8,0,0,0,3,0,2,224,3,0,228,144,0,0,228,160,8,0,0,0,4,0,2,224,3,0,228,144,1,0,228,160,8,0,0,0,5,0,2,224,3,0,228,144,2,0,228,160,8,0,0,0,3,0,4,224,2,0,228,144,0,0,228,160,8,0,0,0,4,0,4,224,2,0,228,144,1,0,228,160,8,0,0,0,5,0,4,224,2,0,228,144,2,0,228,160,1,0,0,0,0,0,3,224,1,0,228,144,255,255,0,0,255,255,255,255,11,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,84,101,120,116,117,114,101,0,255,255,255,255,9,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,78,111,114,109,97,108,77,97,112,0,101,114, };
		#else
		static readonly byte[] byteCode = { 1,9,255,254,204,4,0,0,0,0,0,0,3,0,0,0,2,0,0,0,96,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,87,111,114,108,100,0,61,0,3,0,0,0,2,0,0,0,200,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,86,105,101,119,0,1,61,0,3,0,0,0,2,0,0,0,48,1,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,80,114,111,106,101,99,116,105,111,110,0,0,3,0,0,0,1,0,0,0,104,1,0,0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,76,105,103,104,116,80,111,115,105,116,105,111,110,0,0,0,3,0,0,0,1,0,0,0,168,1,0,0,0,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,76,105,103,104,116,67,111,108,111,114,0,0,3,0,0,0,1,0,0,0,228,1,0,0,0,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,65,109,98,105,101,110,116,76,105,103,104,116,67,111,108,111,114,0,0,0,3,0,0,0,0,0,0,0,28,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,10,0,0,0,83,104,105,110,105,110,101,115,115,0,0,0,3,0,0,0,0,0,0,0,76,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,14,0,0,0,83,112,101,99,117,108,97,114,80,111,119,101,114,0,0,0,7,0,0,0,4,0,0,0,120,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,78,111,114,109,97,108,77,97,112,0,0,0,12,0,0,0,4,0,0,0,88,3,0,0,0,0,0,0,0,0,0,0,2,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,4,0,0,0,164,0,0,0,0,1,0,0,160,2,0,0,156,2,0,0,170,0,0,0,0,1,0,0,184,2,0,0,180,2,0,0,169,0,0,0,0,1,0,0,216,2,0,0,212,2,0,0,171,0,0,0,0,1,0,0,248,2,0,0,244,2,0,0,17,0,0,0,78,111,114,109,97,108,77,97,112,83,97,109,112,108,101,114,0,0,0,0,7,0,0,0,4,0,0,0,136,3,0,0,0,0,0,0,0,0,0,0,3,0,0,0,8,0,0,0,84,101,120,116,117,114,101,0,12,0,0,0,4,0,0,0,100,4,0,0,0,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,4,0,0,0,164,0,0,0,0,1,0,0,172,3,0,0,168,3,0,0,170,0,0,0,0,1,0,0,196,3,0,0,192,3,0,0,169,0,0,0,0,1,0,0,228,3,0,0,224,3,0,0,171,0,0,0,0,1,0,0,4,4,0,0,0,4,0,0,22,0,0,0,68,105,102,102,117,115,101,84,101,120,116,117,114,101,83,97,109,112,108,101,114,0,0,0,5,0,0,0,16,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,15,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,71,111,0,0,14,0,0,0,78,111,114,109,97,108,77,97,112,112,105,110,103,0,0,0,12,0,0,0,1,0,0,0,5,0,0,0,7,0,0,0,4,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,108,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,212,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,64,1,0,0,92,1,0,0,0,0,0,0,0,0,0,0,124,1,0,0,152,1,0,0,0,0,0,0,0,0,0,0,184,1,0,0,212,1,0,0,0,0,0,0,0,0,0,0,252,1,0,0,24,2,0,0,0,0,0,0,0,0,0,0,44,2,0,0,72,2,0,0,0,0,0,0,0,0,0,0,96,2,0,0,116,2,0,0,0,0,0,0,0,0,0,0,136,2,0,0,20,3,0,0,0,0,0,0,0,0,0,0,112,3,0,0,132,3,0,0,0,0,0,0,0,0,0,0,148,3,0,0,32,4,0,0,0,0,0,0,0,0,0,0,184,4,0,0,0,0,0,0,1,0,0,0,176,4,0,0,0,0,0,0,2,0,0,0,146,0,0,0,0,0,0,0,132,4,0,0,128,4,0,0,147,0,0,0,0,0,0,0,156,4,0,0,152,4,0,0,2,0,0,0,4,0,0,0,3,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,1,0,0,0,0,0,0,0,112,4,0,0,0,2,255,255,254,255,86,0,67,84,65,66,28,0,0,0,31,1,0,0,0,2,255,255,5,0,0,0,28,0,0,0,0,0,0,0,24,1,0,0,128,0,0,0,2,0,1,0,1,0,0,0,148,0,0,0,164,0,0,0,180,0,0,0,3,0,1,0,1,0,0,0,204,0,0,0,0,0,0,0,220,0,0,0,2,0,0,0,1,0,0,0,148,0,0,0,164,0,0,0,231,0,0,0,3,0,0,0,1,0,0,0,204,0,0,0,0,0,0,0,248,0,0,0,2,0,2,0,1,0,0,0,8,1,0,0,164,0,0,0,65,109,98,105,101,110,116,76,105,103,104,116,67,111,108,111,114,0,171,171,1,0,3,0,1,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,105,102,102,117,115,101,84,101,120,116,117,114,101,83,97,109,112,108,101,114,0,171,171,4,0,12,0,1,0,1,0,1,0,0,0,0,0,0,0,76,105,103,104,116,67,111,108,111,114,0,78,111,114,109,97,108,77,97,112,83,97,109,112,108,101,114,0,83,112,101,99,117,108,97,114,80,111,119,101,114,0,171,171,0,0,3,0,1,0,1,0,1,0,0,0,0,0,0,0,112,115,95,50,95,48,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,68,51,68,88,57,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,49,53,46,55,55,57,46,48,48,48,48,0,171,171,171,254,255,86,0,80,82,69,83,1,2,88,70,254,255,50,0,67,84,65,66,28,0,0,0,143,0,0,0,1,2,88,70,2,0,0,0,28,0,0,0,0,1,0,0,140,0,0,0,68,0,0,0,2,0,0,0,1,0,0,0,80,0,0,0,96,0,0,0,112,0,0,0,2,0,1,0,1,0,0,0,124,0,0,0,96,0,0,0,76,105,103,104,116,67,111,108,111,114,0,171,1,0,3,0,1,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,83,104,105,110,105,110,101,115,115,0,171,171,0,0,3,0,1,0,1,0,1,0,0,0,0,0,0,0,116,120,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,68,51,68,88,57,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,49,53,46,55,55,57,46,48,48,48,48,0,171,171,171,254,255,12,0,80,82,83,73,3,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,254,255,2,0,67,76,73,84,0,0,0,0,254,255,15,0,70,88,76,67,1,0,0,0,4,0,80,160,2,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,12,0,0,0,240,240,240,240,15,15,15,15,255,255,0,0,81,0,0,5,4,0,15,160,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,2,0,0,0,128,0,0,3,176,31,0,0,2,0,0,0,128,1,0,7,176,31,0,0,2,0,0,0,128,2,0,7,176,31,0,0,2,0,0,0,128,3,0,7,176,31,0,0,2,0,0,0,128,4,0,7,176,31,0,0,2,0,0,0,128,5,0,7,176,31,0,0,2,0,0,0,144,0,8,15,160,31,0,0,2,0,0,0,144,1,8,15,160,66,0,0,3,0,0,15,128,0,0,228,176,0,8,228,160,66,0,0,3,1,0,15,128,0,0,228,176,1,8,228,160,8,0,0,3,2,0,1,128,0,0,228,128,3,0,228,176,8,0,0,3,2,0,2,128,0,0,228,128,4,0,228,176,8,0,0,3,2,0,4,128,0,0,228,128,5,0,228,176,36,0,0,2,0,0,7,128,2,0,228,128,36,0,0,2,2,0,7,128,1,0,228,176,8,0,0,3,4,0,1,128,0,0,228,128,2,0,228,128,2,0,0,3,0,0,8,128,4,0,0,128,4,0,0,128,4,0,0,4,0,0,7,128,0,0,228,128,0,0,255,129,2,0,228,128,36,0,0,2,2,0,7,128,2,0,228,176,11,0,0,3,3,0,8,128,4,0,0,128,4,0,0,160,8,0,0,3,0,0,1,128,0,0,228,128,2,0,228,128,11,0,0,3,2,0,8,128,0,0,0,128,4,0,0,160,32,0,0,3,0,0,8,128,2,0,255,128,2,0,0,160,5,0,0,3,2,0,15,128,0,0,255,128,3,0,228,160,1,0,0,2,0,0,15,128,0,0,228,160,4,0,0,4,0,0,15,128,0,0,228,128,3,0,255,128,1,0,228,160,4,0,0,4,0,0,15,128,0,0,228,128,1,0,228,128,2,0,228,128,1,0,0,2,0,8,15,128,0,0,228,128,255,255,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,140,5,0,0,1,1,254,255,254,255,80,0,67,84,65,66,28,0,0,0,10,1,0,0,1,1,254,255,4,0,0,0,28,0,0,0,0,0,0,0,3,1,0,0,108,0,0,0,2,0,12,0,1,0,0,0,124,0,0,0,140,0,0,0,156,0,0,0,2,0,8,0,4,0,0,0,168,0,0,0,184,0,0,0,248,0,0,0,2,0,4,0,4,0,0,0,168,0,0,0,184,0,0,0,253,0,0,0,2,0,0,0,4,0,0,0,168,0,0,0,184,0,0,0,76,105,103,104,116,80,111,115,105,116,105,111,110,0,171,171,1,0,3,0,1,0,3,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,114,111,106,101,99,116,105,111,110,0,171,3,0,3,0,4,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,105,101,119,0,87,111,114,108,100,0,118,115,95,49,95,49,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,68,51,68,88,57,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,49,53,46,55,55,57,46,48,48,48,48,0,254,255,161,0,80,82,69,83,1,2,88,70,254,255,49,0,67,84,65,66,28,0,0,0,139,0,0,0,1,2,88,70,1,0,0,0,28,0,0,0,0,1,0,0,136,0,0,0,48,0,0,0,2,0,0,0,3,0,0,0,56,0,0,0,72,0,0,0,86,105,101,119,0,171,171,171,3,0,3,0,4,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,116,120,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,68,51,68,88,57,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,57,46,49,53,46,55,55,57,46,48,48,48,48,0,171,171,171,254,255,12,0,80,82,83,73,13,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,13,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,254,255,2,0,67,76,73,84,0,0,0,0,254,255,91,0,70,88,76,67,9,0,0,0,1,0,0,16,1,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,1,0,0,16,1,0,0,0,0,0,0,0,2,0,0,0,7,0,0,0,0,0,0,0,7,0,0,0,5,0,0,0,1,0,0,16,1,0,0,0,0,0,0,0,2,0,0,0,11,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,3,0,16,16,1,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,3,0,80,160,2,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,8,0,0,0,3,0,80,160,2,0,0,0,0,0,0,0,7,0,0,0,1,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,12,0,0,0,3,0,80,160,2,0,0,0,0,0,0,0,7,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,8,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,3,0,64,32,2,0,0,0,0,0,0,0,7,0,0,0,8,0,0,0,0,0,0,0,7,0,0,0,12,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,3,0,64,32,2,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,52,0,0,0,240,240,240,240,15,15,15,15,255,255,0,0,31,0,0,0,0,0,0,128,0,0,15,144,31,0,0,0,5,0,0,128,1,0,15,144,31,0,0,0,3,0,0,128,2,0,15,144,31,0,0,0,7,0,0,128,3,0,15,144,31,0,0,0,6,0,0,128,4,0,15,144,9,0,0,0,0,0,8,128,0,0,228,144,3,0,228,160,9,0,0,0,0,0,1,128,0,0,228,144,0,0,228,160,9,0,0,0,0,0,2,128,0,0,228,144,1,0,228,160,9,0,0,0,0,0,4,128,0,0,228,144,2,0,228,160,9,0,0,0,1,0,1,128,0,0,228,128,4,0,228,160,9,0,0,0,1,0,2,128,0,0,228,128,5,0,228,160,9,0,0,0,1,0,4,128,0,0,228,128,6,0,228,160,9,0,0,0,1,0,8,128,0,0,228,128,7,0,228,160,9,0,0,0,0,0,1,192,1,0,228,128,8,0,228,160,9,0,0,0,0,0,2,192,1,0,228,128,9,0,228,160,9,0,0,0,0,0,4,192,1,0,228,128,10,0,228,160,9,0,0,0,0,0,8,192,1,0,228,128,11,0,228,160,2,0,0,0,1,0,7,224,0,0,228,129,12,0,228,160,2,0,0,0,2,0,7,224,0,0,228,128,13,0,228,161,8,0,0,0,3,0,1,224,4,0,228,144,0,0,228,160,8,0,0,0,4,0,1,224,4,0,228,144,1,0,228,160,8,0,0,0,5,0,1,224,4,0,228,144,2,0,228,160,8,0,0,0,3,0,2,224,3,0,228,144,0,0,228,160,8,0,0,0,4,0,2,224,3,0,228,144,1,0,228,160,8,0,0,0,5,0,2,224,3,0,228,144,2,0,228,160,8,0,0,0,3,0,4,224,2,0,228,144,0,0,228,160,8,0,0,0,4,0,4,224,2,0,228,144,1,0,228,160,8,0,0,0,5,0,4,224,2,0,228,144,2,0,228,160,1,0,0,0,0,0,3,224,1,0,228,144,255,255,0,0,255,255,255,255,11,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,84,101,120,116,117,114,101,0,255,255,255,255,9,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,10,0,0,0,78,111,114,109,97,108,77,97,112,0,0,0, };
		#endif

		#endregion
	}
}
